VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "VBProc"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
Option Explicit

Private mLoaded As Boolean

Private mCurrentNestLevel As Long

Private mName As String
Private mParentName As String

Private mComplexity As Long

Private mCounters As Counters
Private mCurrentLine As VBLine

Const kLongLineLength  As Long = 60

Public Function CounterValue(which As eCounterType) As Long
    CounterValue = mCounters.CounterValue(which)
End Function

Public Sub Load(procLines() As VBLine)

Dim idx As Long
Dim inputLine As String
Dim foundContinuation As Boolean

    InitCounters

    For idx = LBound(procLines) To UBound(procLines)
        
        Set mCurrentLine = procLines(idx)
        If Not (mCurrentLine Is Nothing) Then   '##MAW## Hack.
            ProcessLine
        End If
        
    Next
    
    mLoaded = True
    
End Sub

Public Property Get Complexity() As Long

    Complexity = mCounters.Complexity

End Property

Public Property Get ParentName() As String
    ParentName = mParentName
End Property

Public Property Get Name() As String
    Name = mName
End Property

Public Property Let ParentName(Name As String)
    mParentName = Name
End Property

Public Property Get Counters() As Counters
    Set Counters = mCounters
End Property

Private Sub ProcessLine()

Dim word1 As String
    
    With mCurrentLine

        word1 = .TextWord(1)

        CheckFirstWord word1

        CheckFirstAndSecondWords word1 & "\" & .TextWord(2)

        CheckIfs

        If .HasAGoto Then
            mCounters.Add ecGotos, 1
        End If
        
        If .IsADoingLine Then
            AddADoingLine mCurrentLine
        ElseIf .IsProcHeaderLine Then
            ExtractProcName
            CountParameters
        ElseIf .IsADeclaration Then
            AddDeclarations .DeclaredVariableCount
            CheckForOneCharVars
        ElseIf .IsAComment Then
            mCounters.Add ecComments, 1
        End If

    End With

End Sub

Private Sub CheckForOneCharVars()

Dim decVarIndex As Long
    
    With mCurrentLine

        For decVarIndex = 1 To .DeclaredVariableCount
            If Len(.DeclaredVariable(decVarIndex)) = 1 Then
                mCounters.Add ecOneCharVars, 1
            End If
        Next
            
    End With
            
End Sub

Private Sub CheckIfs()

    With mCurrentLine

        If .IsAnIf Then
            mCounters.Add ecIfs, 1
            IncreaseNestLevel
        End If
        
        If .IsAnElseIf Then
            mCounters.Add ecElseIfs, 1
        End If
        
    End With
    
End Sub

Private Sub CheckFirstAndSecondWords(wordpair As String)

    Select Case wordpair
    Case "end\if", "end\select"
            DecreaseNestLevel
    End Select

End Sub

Private Sub CheckFirstWord(Word As String)

    Select Case Word
    Case "for", "do", "while"
        mCounters.Add ecLoops, 1
        IncreaseNestLevel
    Case "with"
        mCounters.Add ecWiths, 1
    Case "select"
        mCounters.Add ecSelects, 1
        IncreaseNestLevel
    Case "loop", "next", "wend"
        DecreaseNestLevel
    End Select

End Sub

Private Sub AddADoingLine(theLine As VBLine)

    mCounters.Add ecLines, 1
    
    With theLine

        If .CodeLength > kLongLineLength Then
            mCounters.Add ecLongLines, 1
        End If
        
        If .IsAnIif Then
            mCounters.Add ecIifs, 1
        End If

    End With
    
End Sub

Private Sub AddDeclarations(numDeclares As Long)

    mCounters.Add ecDeclares, numDeclares
    If numDeclares > 1 Then
        mCounters.Add ecMultiDimCount, 1
    End If

End Sub

Private Sub IncreaseNestLevel()
    mCurrentNestLevel = mCurrentNestLevel + 1
    If mCurrentNestLevel > mCounters.CounterValue(ecHighestNestLevel) Then
        mCounters.SetCounter ecHighestNestLevel, mCurrentNestLevel
    End If
End Sub

Private Sub DecreaseNestLevel()
    mCurrentNestLevel = mCurrentNestLevel - 1
End Sub

Private Sub ExtractProcName()

Dim firstBracket As Long
Dim firstChar As Long

    firstBracket = InStr(mCurrentLine.Text, "(")
    firstChar = firstBracket
    
    Do Until Mid(mCurrentLine.Text, firstChar - 1, 1) = " "
        firstChar = firstChar - 1
    Loop
    
    mName = Mid(mCurrentLine.Text, firstChar, firstBracket - firstChar)
        
End Sub

Private Sub CountParameters()

Dim charIndex As Long
Dim firstBracket As Long
Dim thisChar As String
Dim inString As Boolean

    firstBracket = InStr(mCurrentLine.Text, "(")
    
    If Mid(mCurrentLine.Text, firstBracket + 1, 1) <> ")" Then
    
        mCounters.SetCounter ecParameters, 1
        
        For charIndex = 1 To Len(mCurrentLine.Text)
            thisChar = Mid(mCurrentLine.Text, charIndex, 1)
            If thisChar = "," And Not inString Then
                mCounters.Add ecParameters, 1
            ElseIf thisChar = """" Then
                inString = Not inString
            End If
        Next

    Else
        mCounters.SetCounter ecParameters, 0
    End If

End Sub

Private Sub InitCounters()

    mCounters.Reset

    mCurrentNestLevel = 0

End Sub

Private Sub Class_Initialize()
    Set mCounters = New Counters
    InitCounters
    Set mCurrentLine = New VBLine
End Sub

Private Sub Class_Terminate()
    Set mCurrentLine = Nothing
    Set mCounters = Nothing
End Sub
